package org.dark.web;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dark.web.scanner.Pair;
import org.dark.web.scanner.TableScanner;
import org.dromara.streamquery.stream.plugin.mybatisplus.Database;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class GenericWebApi implements InitializingBean {

    @Value("${stream-web.base-packages}")
    List<String> basePackages;

    List<TableScanner> tableScanners;

    public List<Object> getAll(String entity) {
        Class<?> entityClazz = getEntityClazz(entity);
        if (null == entityClazz) {
            return new ArrayList<>();
        }
        return (List<Object>) Database.list(entityClazz);
    }

    public Object getById(String entity, String id) {
        Class<?> entityClazz = getEntityClazz(entity);
        if (null == entityClazz) {
            return null;
        }
        return Database.getById(id, entityClazz);
    }

    public void deleteById(String entity, String id) {
        Class<?> entityClazz = getEntityClazz(entity);
        if (null == entityClazz) {
            return;
        }
        Database.removeById(id, entityClazz);
    }

    public int save(String entity, Object entityObject) {
        Pair pair = getEntityClazzAndMapperPair(entity);
        if (null == pair) {
            return 0;
        }
        return ((BaseMapper) pair.getMapper()).insert(entityObject);
    }

    public int updateById(String entity, Object entityObject) {
        Pair pair = getEntityClazzAndMapperPair(entity);
        if (null == pair) {
            return 0;
        }
        return ((BaseMapper) pair.getMapper()).updateById(entityObject);
    }

    private Class<?> getEntityClazz(String entity) {
        return tableScanners.stream()
                .filter(scanner -> scanner.getEntity(entity) != null)
                .map(scanner -> scanner.getEntity(entity))
                .findAny()
                .orElse(null);
    }

    private Pair getEntityClazzAndMapperPair(String entity) {
        return tableScanners.stream()
                .filter(scanner -> scanner.getEntity(entity) != null)
                .map(scanner -> new Pair(scanner.getEntity(entity), scanner.getMapper(entity)))
                .findAny()
                .orElse(null);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (CollectionUtils.isEmpty(basePackages)) {
            return;
        }
        tableScanners = basePackages.stream().map(TableScanner::new).collect(Collectors.toList());
    }
}